﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;


namespace MapEditor
{

    enum Area { none = 0, top_left = 1, top_right = 2, bottom_left = 3, bottom_right = 4 };
    class QNode
    {
        const int QNODE_MAX = 500;
        private int _id;
        private Rectangle _bound;
        private List<GameObject> _objList;

        private QNode _tl, _tr, _bl, _br;

        public QNode(int parentID, Area area, Rectangle bound)
        {
            _id = parentID * 8 + (int)area;
            _bound = bound;
            _objList = new List<GameObject>();
        }

        public Rectangle Bound
        {
            get { return _bound; }
        }

        ////////
        //1. Check if o.MovingBound intersects with this._bound (using Rectangle.Intersect). return if not.
        //2. Check if this._bound.Height > QNODE_MAX. if > then divide, else this._objList.Add(o);
        //// Divide: Check if this._tl == null then define this._tl this._tr...... new QNode(this._id, Area.top_left, new Rectangle(x, y, xHalf, xHalf));
        //// xHalf = this._bound.Width/2, x= bound.x, y = bound.y
        //// then  _tl.AddObj(o) (4nodes)

        public void AddObj(GameObject o)
        {
            Rectangle tempRect = Rectangle.Intersect(this._bound, o.MovingBound);
            if (tempRect.Width == 0 || tempRect.Height == 0)
                return;
            if (this._bound.Height > QNODE_MAX)//then divide
            {
                if (this._tl == null)
                {
                    int xHalf = this._bound.Width / 2;

                    int x = this._bound.X;
                    int y = this._bound.Y;

                    this._tl = new QNode(this._id, Area.top_left, new Rectangle(x, y, xHalf, xHalf));
                    this._tr = new QNode(this._id, Area.top_right, new Rectangle(x + xHalf, y, xHalf, xHalf));
                    this._bl = new QNode(this._id, Area.bottom_left, new Rectangle(x, y + xHalf, xHalf, xHalf));
                    this._br = new QNode(this._id, Area.bottom_right, new Rectangle(x + xHalf, y + xHalf, xHalf, xHalf));
                }
                this._tl.AddObj(o);
                this._tr.AddObj(o);
                this._bl.AddObj(o);
                this._br.AddObj(o);
            }
            else this._objList.Add(o);
        }

        public void SerializeQ(List<string> NodeInfoList)
        {
            //" " must be added to end line (iterator in c++ need " " to operate successfully)
            string temp = _id.ToString() + " " + _bound.X.ToString() + " " + _bound.Y.ToString()
                + " " + _bound.Width.ToString() + " " + _bound.Height.ToString() + " ";

            if (this._tl != null)
            {
                NodeInfoList.Add(temp);
                this._tl.SerializeQ(NodeInfoList);
                this._tr.SerializeQ(NodeInfoList);
                this._bl.SerializeQ(NodeInfoList);
                this._br.SerializeQ(NodeInfoList);
            }
            else
            {
                foreach (GameObject o in this._objList)
                {
                    //" " must be added to end line (iterator in c++ need " " to operate successfully)
                    temp += o.ID.ToString() + " ";
                }
                NodeInfoList.Add(temp);
            }
        }
    }
}
